/**
 * 任务服务
 * 负责任务的增删改查等操作
 */
import { dbService, TABLES, Category } from './database'
import { generateUUID } from '../utils/id'

/**
 * 任务优先级类型
 */
export type TaskPriority = 'high' | 'medium' | 'low'

/**
 * 任务类型定义
 */
export interface Task {
  id: string
  title: string
  categoryId?: string
  category?: Category  // 关联的分类对象，非数据库字段，由服务层填充
  priority: TaskPriority
  date?: string
  timeRange?: string
  completed: boolean
  reminder: boolean
  description?: string
  attachments: any[]
  createdAt: string
  updatedAt: string
}

/**
 * 创建任务参数
 */
export interface CreateTaskParams {
  title: string
  categoryId?: string
  priority?: TaskPriority
  date?: string
  timeRange?: string
  reminder?: boolean
  description?: string
  attachments?: any[]
}

/**
 * 任务服务类
 */
class TaskService {
  /**
   * 创建任务
   * @param params 任务参数
   * @returns 创建的任务ID
   */
  async createTask(params: CreateTaskParams): Promise<string> {
    try {
      // 生成任务ID
      const id = generateUUID()
      const now = new Date().toISOString()

      // 如果没有提供分类ID，使用默认分类
      let categoryId = params.categoryId
      if (!categoryId) {
        const defaultCategory = await dbService.getDefaultCategory('task')
        if (defaultCategory) {
          categoryId = defaultCategory.id
        }
      }

      // 创建任务对象
      const task: Task = {
        id,
        title: params.title,
        categoryId: categoryId,
        priority: params.priority || 'medium',
        date: params.date,
        timeRange: params.timeRange,
        completed: false,
        reminder: params.reminder ?? false,
        description: params.description,
        attachments: params.attachments || [],
        createdAt: now,
        updatedAt: now
      }

      // 存储任务到数据库
      const dbTask = {
        id: task.id,
        title: task.title,
        categoryId: task.categoryId || null,
        priority: task.priority,
        date: task.date || null,
        timeRange: task.timeRange || null,
        completed: 0, // SQLite中布尔值使用0/1表示
        reminder: task.reminder ? 1 : 0,
        description: task.description || null,
        attachments: JSON.stringify(task.attachments),
        createdAt: task.createdAt,
        updatedAt: task.updatedAt
      }

      // 插入数据库
      const success = await dbService.insert(TABLES.TASKS, dbTask)
      if (!success) {
        throw new Error('任务创建失败')
      }

      return id
    } catch (error) {
      console.error('创建任务失败:', error)
      throw error
    }
  }

  /**
   * 获取任务详情
   * @param id 任务ID
   * @returns 任务详情
   */
  async getTaskById(id: string): Promise<Task | null> {
    try {
      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        `id = ${dbService['formatValue'](id)}`
      )

      if (!result.length) {
        return null
      }

      // 将数据库结果转换为Task对象
      const task = this.mapDbTaskToTask(result[0])
      
      // 加载分类信息
      if (task.categoryId) {
        await this.loadTaskCategory(task)
      }
      
      return task
    } catch (error) {
      console.error(`获取任务 ${id} 失败:`, error)
      return null
    }
  }

  /**
   * 获取未完成的任务列表
   * @returns 未完成任务列表
   */
  async getIncompleteTasks(): Promise<Task[]> {
    try {
      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        'completed = 0',
        // 根据优先级和日期排序
        `CASE priority 
          WHEN 'high' THEN 1 
          WHEN 'medium' THEN 2 
          WHEN 'low' THEN 3 
         END, 
         CASE 
          WHEN date IS NULL THEN 1
          ELSE 0
         END, 
         date ASC, 
         createdAt DESC`
      )

      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 批量加载分类信息
      await this.loadTaskCategories(tasks)
      
      return tasks
    } catch (error) {
      console.error('获取未完成任务列表失败:', error)
      return []
    }
  }

  /**
   * 获取已完成的任务列表
   * @param limit 限制返回的数量，默认20条
   * @returns 已完成任务列表
   */
  async getCompletedTasks(limit: number = 20): Promise<Task[]> {
    try {
      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        'completed = 1',
        'updatedAt DESC',
        limit
      )

      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 批量加载分类信息
      await this.loadTaskCategories(tasks)
      
      return tasks
    } catch (error) {
      console.error('获取已完成任务列表失败:', error)
      return []
    }
  }

  /**
   * 更新任务
   * @param id 任务ID
   * @param updates 要更新的字段
   * @returns 是否更新成功
   */
  async updateTask(id: string, updates: Partial<CreateTaskParams>): Promise<boolean> {
    try {
      // 获取当前任务
      const task = await this.getTaskById(id)
      if (!task) {
        throw new Error(`任务 ${id} 不存在`)
      }

      // 准备更新数据
      const dbUpdates: Record<string, any> = {
        ...updates,
        updatedAt: new Date().toISOString()
      }

      // 处理特殊字段
      if (updates.attachments !== undefined) {
        dbUpdates.attachments = JSON.stringify(updates.attachments)
      }
      if (updates.reminder !== undefined) {
        dbUpdates.reminder = updates.reminder ? 1 : 0
      }

      // 更新数据库
      const success = await dbService.update(
        TABLES.TASKS,
        dbUpdates,
        `id = ${dbService['formatValue'](id)}`
      )

      return success
    } catch (error) {
      console.error(`更新任务 ${id} 失败:`, error)
      return false
    }
  }

  /**
   * 标记任务完成状态
   * @param id 任务ID
   * @param completed 是否完成
   * @returns 是否更新成功
   */
  async completeTask(id: string, completed: boolean): Promise<boolean> {
    try {
      // 更新数据库
      const success = await dbService.update(
        TABLES.TASKS,
        {
          completed: completed ? 1 : 0,
          updatedAt: new Date().toISOString()
        },
        `id = ${dbService['formatValue'](id)}`
      )

      return success
    } catch (error) {
      console.error(`更新任务 ${id} 完成状态失败:`, error)
      return false
    }
  }

  /**
   * 获取任务分类列表
   * @returns 任务分类列表
   */
  async getTaskCategories(): Promise<Category[]> {
    try {
      return await dbService.getCategories('task')
    } catch (error) {
      console.error('获取任务分类列表失败:', error)
      return []
    }
  }

  /**
   * 创建任务分类
   * @param name 分类名称
   * @param icon 分类图标
   * @param color 分类颜色
   * @param isDefault 是否设置为默认分类
   * @returns 是否创建成功
   */
  async createTaskCategory(
    name: string, 
    icon?: string, 
    color?: string,
    isDefault?: boolean
  ): Promise<boolean> {
    try {
      // 创建分类
      const success = await dbService.addCategory({
        name,
        type: 'task',
        icon,
        color,
        sort: 0 // 新创建的分类放在最前面
      })
      
      // 如果需要设置为默认分类
      if (success && isDefault) {
        // 获取刚创建的分类ID
        const categories = await this.getTaskCategories()
        const createdCategory = categories.find(c => c.name === name)
        
        if (createdCategory) {
          // 设置为默认分类
          await dbService.setDefaultCategory(createdCategory.id)
        }
      }
      
      return success
    } catch (error) {
      console.error('创建任务分类失败:', error)
      return false
    }
  }

  /**
   * 根据分类获取任务列表
   * @param categoryId 分类ID
   * @returns 任务列表
   */
  async getTasksByCategoryId(categoryId: string): Promise<Task[]> {
    try {
      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        `categoryId = ${dbService['formatValue'](categoryId)}`,
        'completed ASC, date ASC, createdAt DESC'
      )

      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 加载分类信息
      await this.loadTaskCategories(tasks)
      
      return tasks
    } catch (error) {
      console.error(`获取分类 ${categoryId} 的任务列表失败:`, error)
      return []
    }
  }

  /**
   * 加载单个任务的分类信息
   * @param task 任务对象
   */
  private async loadTaskCategory(task: Task): Promise<void> {
    if (!task.categoryId) return
    
    try {
      const categories = await dbService.query<Category>(
        TABLES.CATEGORIES,
        ['*'],
        `id = ${dbService['formatValue'](task.categoryId)}`
      )
      
      if (categories.length > 0) {
        task.category = categories[0]
      }
    } catch (error) {
      console.error(`加载任务 ${task.id} 的分类信息失败:`, error)
    }
  }

  /**
   * 批量加载任务的分类信息
   * @param tasks 任务列表
   */
  private async loadTaskCategories(tasks: Task[]): Promise<void> {
    if (tasks.length === 0) return
    
    try {
      // 收集所有不重复的分类ID
      const categoryIdSet = new Set<string>()
      tasks.forEach(task => {
        if (task.categoryId) {
          categoryIdSet.add(task.categoryId)
        }
      })
      
      const categoryIds = Array.from(categoryIdSet)
      if (categoryIds.length === 0) return
      
      // 查询所有相关分类
      const categories = await dbService.query<Category>(
        TABLES.CATEGORIES,
        ['*'],
        `id IN (${categoryIds.map(id => dbService['formatValue'](id)).join(',')})`
      )
      
      // 构建分类映射
      const categoryMap = new Map<string, Category>()
      for (const category of categories) {
        categoryMap.set(category.id, category)
      }
      
      // 为每个任务设置分类信息
      for (const task of tasks) {
        if (task.categoryId && categoryMap.has(task.categoryId)) {
          task.category = categoryMap.get(task.categoryId)
        }
      }
    } catch (error) {
      console.error('批量加载任务分类信息失败:', error)
    }
  }

  /**
   * 将数据库任务对象转换为Task接口对象
   * @param dbTask 数据库任务对象
   * @returns Task接口对象
   */
  private mapDbTaskToTask(dbTask: any): Task {
    return {
      id: dbTask.id,
      title: dbTask.title,
      categoryId: dbTask.categoryId,
      priority: dbTask.priority as TaskPriority,
      date: dbTask.date,
      timeRange: dbTask.timeRange,
      completed: !!dbTask.completed,
      reminder: !!dbTask.reminder,
      description: dbTask.description,
      attachments: dbTask.attachments ? JSON.parse(dbTask.attachments) : [],
      createdAt: dbTask.createdAt,
      updatedAt: dbTask.updatedAt
    }
  }

  /**
   * 删除任务
   * @param id 任务ID
   * @returns 是否删除成功
   */
  async deleteTask(id: string): Promise<boolean> {
    try {
      // 从数据库删除
      const success = await dbService.delete(
        TABLES.TASKS,
        `id = ${dbService['formatValue'](id)}`
      )

      return success
    } catch (error) {
      console.error(`删除任务 ${id} 失败:`, error)
      return false
    }
  }

  /**
   * 搜索任务
   * @param keyword 关键词
   * @returns 匹配的任务列表
   */
  async searchTasks(keyword: string): Promise<Task[]> {
    try {
      // 安全处理关键词，防止SQL注入
      const safeKeyword = keyword.replace(/'/g, "''")
      
      // 构建搜索条件
      const whereClause = `
        title LIKE '%${safeKeyword}%' 
        OR description LIKE '%${safeKeyword}%'
      `

      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        whereClause,
        // 排序：未完成的优先，然后按优先级和日期排序
        `completed ASC,
         CASE priority 
          WHEN 'high' THEN 1 
          WHEN 'medium' THEN 2 
          WHEN 'low' THEN 3 
         END, 
         createdAt DESC`
      )

      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 加载分类信息
      await this.loadTaskCategories(tasks)
      
      return tasks
    } catch (error) {
      console.error(`搜索任务失败，关键词: ${keyword}:`, error)
      return []
    }
  }

  /**
   * 获取今天的任务
   * @returns 今天的任务列表
   */
  async getTodayTasks(): Promise<Task[]> {
    try {
      // 获取今天的日期，格式YYYY-MM-DD
      const today = new Date().toISOString().split('T')[0]

      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        `date = ${dbService['formatValue'](today)}`,
        // 排序：未完成的优先，然后按优先级排序
        `completed ASC,
         CASE priority 
          WHEN 'high' THEN 1 
          WHEN 'medium' THEN 2 
          WHEN 'low' THEN 3 
         END`
      )

      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 加载分类信息
      await this.loadTaskCategories(tasks)
      
      return tasks
    } catch (error) {
      console.error('获取今天的任务列表失败:', error)
      return []
    }
  }

  /**
   * 获取按日期分组的任务
   * @param startDate 开始日期
   * @param endDate 结束日期
   * @returns 按日期分组的任务
   */
  async getTasksByDateRange(startDate: string, endDate: string): Promise<Record<string, Task[]>> {
    try {
      // 查询数据库
      const result = await dbService.query<any>(
        TABLES.TASKS,
        ['*'],
        `date >= ${dbService['formatValue'](startDate)} AND date <= ${dbService['formatValue'](endDate)}`,
        `date ASC, 
         completed ASC,
         CASE priority 
          WHEN 'high' THEN 1 
          WHEN 'medium' THEN 2 
          WHEN 'low' THEN 3 
         END`
      )

      // 将结果按日期分组
      const tasksByDate: Record<string, Task[]> = {}
      
      // 将数据库结果转换为Task对象
      const tasks = result.map(this.mapDbTaskToTask)
      
      // 加载分类信息
      await this.loadTaskCategories(tasks)
      
      // 按日期分组
      for (const task of tasks) {
        const date = task.date || 'undefined'
        
        if (!tasksByDate[date]) {
          tasksByDate[date] = []
        }
        
        tasksByDate[date].push(task)
      }

      return tasksByDate
    } catch (error) {
      console.error(`获取日期范围 ${startDate} 至 ${endDate} 的任务失败:`, error)
      return {}
    }
  }

  /**
   * 获取按分类分组的任务统计
   * @returns 按分类分组的任务数量
   */
  async getTaskCountByCategory(): Promise<Record<string, number>> {
    try {
      // 获取所有分类
      const categories = await dbService.getCategories('task')
      const countByCategory: Record<string, number> = {}
      
      // 初始化计数
      for (const category of categories) {
        countByCategory[category.id] = 0
      }
      
      // 添加未分类选项
      countByCategory['undefined'] = 0
      
      // 查询数据库，按分类ID分组
      const result = await dbService.query<{ categoryId: string | null; count: number }>(
        TABLES.TASKS,
        ['categoryId', 'COUNT(*) as count'],
        '',
        'categoryId'
      )
      
      // 更新计数
      for (const row of result) {
        const categoryId = row.categoryId || 'undefined'
        countByCategory[categoryId] = row.count
      }
      
      return countByCategory
    } catch (error) {
      console.error('获取任务分类统计失败:', error)
      return {}
    }
  }

  /**
   * 更新任务分类
   * @param id 分类ID
   * @param name 分类名称
   * @param icon 分类图标
   * @param color 分类颜色
   * @param isDefault 是否设置为默认分类
   * @returns 是否更新成功
   */
  async updateTaskCategory(
    id: string, 
    name: string, 
    icon?: string, 
    color?: string, 
    isDefault?: boolean
  ): Promise<boolean> {
    try {
      const now = new Date().toISOString()
      
      // 准备更新数据
      const updates: Record<string, any> = {
        name,
        updatedAt: now
      }
      
      if (icon !== undefined) {
        updates.icon = icon
      }
      
      if (color !== undefined) {
        updates.color = color
      }
      
      if (isDefault !== undefined) {
        updates.isDefault = isDefault ? 1 : 0
      }
      
      // 更新数据库
      const success = await dbService.updateCategory(id, updates)
      
      return success
    } catch (error) {
      console.error('更新任务分类失败:', error)
      return false
    }
  }

  /**
   * 删除任务分类
   * @param id 分类ID
   * @returns 是否删除成功
   */
  async deleteTaskCategory(id: string): Promise<boolean> {
    try {
      // 获取默认分类，用于重新分配任务
      const defaultCategory = await dbService.getDefaultCategory('task')
      
      if (!defaultCategory) {
        throw new Error('未找到默认分类')
      }
      
      // 将该分类下的任务移动到默认分类
      const success = await dbService.update(
        TABLES.TASKS,
        { categoryId: defaultCategory.id },
        `categoryId = ${dbService['formatValue'](id)}`
      )
      
      if (!success) {
        throw new Error('移动任务失败')
      }
      
      // 删除分类
      const deleteSuccess = await dbService.deleteCategory(id)
      
      return deleteSuccess
    } catch (error) {
      console.error('删除任务分类失败:', error)
      return false
    }
  }

  /**
   * 保存任务（自动判断是创建还是更新）
   * @param task 任务对象
   * @returns 是否保存成功
   */
  async saveTask(task: Task): Promise<boolean> {
    try {
      const now = new Date().toISOString();
      
      // 如果任务有ID，则为更新操作
      if (task.id) {
        console.log('更新现有任务:', task.id);
        
        // 准备更新数据
        const updateData: Partial<CreateTaskParams> = {
          title: task.title,
          categoryId: task.categoryId,
          priority: task.priority,
          date: task.date,
          timeRange: task.timeRange,
          reminder: task.reminder,
          description: task.description,
          attachments: task.attachments
        };
        
        // 执行更新
        return await this.updateTask(task.id, updateData);
      } 
      // 否则为创建操作
      else {
        console.log('创建新任务');
        
        // 准备创建数据
        const createParams: CreateTaskParams = {
          title: task.title,
          categoryId: task.categoryId,
          priority: task.priority,
          date: task.date,
          timeRange: task.timeRange,
          reminder: task.reminder,
          description: task.description,
          attachments: task.attachments
        };
        
        // 执行创建
        const newId = await this.createTask(createParams);
        
        // 创建成功后，将新ID设置到原任务对象
        if (newId) {
          task.id = newId;
          task.createdAt = now;
          task.updatedAt = now;
          return true;
        }
        
        return false;
      }
    } catch (error) {
      console.error('保存任务失败:', error);
      return false;
    }
  }
}

// 导出任务服务单例
export const taskService = new TaskService() 